package cn.tlb.gl.tri3dtexture;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import cn.tlb.xutilsdownload.R;

public class TriangleTextureActivity extends AppCompatActivity {

    private static final float FACTOR = 20;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyGLSurfaceView(this));
    }

    private float rotateX;
    private float rotateY;
    private float touchX;
    private float touchY;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
                touchX = event.getX();
                touchY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                rotateX += (event.getX()-touchX)/20;
                rotateY += ((event.getY()-touchY))/20;
//                touchX = event.getX();
//                touchY = event.getY();
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }

    class MyGLSurfaceView extends GLSurfaceView{

        public MyGLSurfaceView(Context context) {
            super(context);
            setRenderer(new TriangleTextureRenderer(context));
        }
    }


    class TriangleTextureRenderer implements GLSurfaceView.Renderer{

        float[] vertex = {
                -0.5f, 	-0.57735f, 	0,
                0.5f, 	-0.57735f, 	0,
                0,		0.28867f,	0,
                0,		0,			0.86602f
        };

        byte[] indeces = {
                0,2,3,
                1,2,3,
                2,3,0,
                0,1,2
        };

        float[] textures = {
                0,2,0,2,0,0,
                0,2,0,2,0,0,
                0,2,0,2,0,0,
                0,2,0,2,0,0
        };

        FloatBuffer vertexBuffer;
        ByteBuffer indicesByteBuffer;
        FloatBuffer textureBuffer;
        Context context;
        int textureID;
        public TriangleTextureRenderer(Context context) {
            vertexBuffer = array2FloatBuffer(vertex);
            indicesByteBuffer = ByteBuffer.wrap(indeces);
            textureBuffer = array2FloatBuffer(textures);
            this.context = context;
        }

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            gl.glDisable(GL10.GL_DITHER);
            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
            gl.glShadeModel(GL10.GL_SMOOTH);
            gl.glClearColor(255, 0, 0, 0);
            gl.glEnable(GL10.GL_TEXTURE_2D);
            gl.glEnable(GL10.GL_DEPTH_TEST);
            gl.glDepthFunc(GL10.GL_LEQUAL);

            // load texture
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.skycubemap1);
            int[] textures = new int[1];
            gl.glGenTextures(1, textures, 0);
            textureID = textures[0];
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

            bitmap.recycle();
        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            gl.glViewport(0, 0, width, height);
            gl.glLoadIdentity();
            gl.glMatrixMode(GL10.GL_PROJECTION);
            float ratio = (float)width/height;
            gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
        }

        @Override
        public void onDrawFrame(GL10 gl) {
            gl.glClear(GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_COLOR_BUFFER_BIT);
            gl.glMatrixMode(GL10.GL_MODELVIEW);
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            // draw triangle
            gl.glLoadIdentity();
            gl.glTranslatef(0, 0, -2);
            gl.glRotatef(rotateX, 0, .2f, 0);
            gl.glRotatef(rotateY, 0.2f, 0, 0);
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
            gl.glDrawElements(GL10.GL_TRIANGLES, indicesByteBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indicesByteBuffer);

            gl.glFinish();
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        }

        private FloatBuffer array2FloatBuffer(float fs[]){
            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(fs.length * 4);
            byteBuffer.order(ByteOrder.nativeOrder());
            FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
            floatBuffer.put(fs);
            floatBuffer.position(0);
            return floatBuffer;
        }
    }
}